home *** CD-ROM | disk | FTP | other *** search
/ Aminet 22 / Aminet 22 (1997)(GTI - Schatztruhe)[!][Dec 1997].iso / Aminet / util / misc / cookietool.lha / cookietool / strstuff.c < prev    next >
C/C++ Source or Header  |  1997-09-20  |  5KB  |  213 lines

  1. /*========================================================================*\
  2.  |  File: strstuff.c                                   Date: 20 Sep 1997  |
  3.  *------------------------------------------------------------------------*
  4.  |   Some string functions, similar to those from the standard library    |
  5.  |                  in <string.h>, but more flexible.                     |
  6.  |   You must call str_setup() before using any of these functions !!!    |
  7.  |                                                                        |
  8. \*========================================================================*/
  9.  
  10. #include <stddef.h>
  11. #include <stdio.h>
  12. #include "strstuff.h"
  13.  
  14. UBYTE to_upper[ 256 ];            /* conversion table */
  15. int   is_space[ 256 ];            /* lookup table */
  16. int bordermode, case_sense;
  17.  
  18.  
  19.  
  20. /*
  21.  * Set up a to_upper[] table that can convert all national characters from
  22.  * the ISO 8859-1/ECMA 94 charset to uppercase, not only 'a'-'z'.
  23.  * Depending on the global variable <case_sense> this table may just as 
  24.  * well do nothing at all.  
  25.  * Similarly, the is_space[] table which is built here may call anything 
  26.  * but alphanumerics a 'space', depending on the setting of <bordermode>.
  27.  */
  28. void str_setup( int bm, int cs )
  29. {  
  30.   int c, d;
  31.  
  32.   bordermode = bm;
  33.   case_sense = cs;              /* set global variables */
  34.   for( c = 0; c < 256; c++ )
  35.     {
  36.       to_upper[ c ] = c;
  37.       is_space[ c ] = ( bordermode < 2 || (c & 0x7f) <= ' ' );
  38.     }
  39.   for( c = 'a'; c <= 'z'; c++ )
  40.     {
  41.       d = c + 'A' - 'a';
  42.       to_upper[ c ] = d;
  43.       is_space[ c ] = 0;
  44.       is_space[ d ] = 0;
  45.     }
  46.   for( c = '0'; c <= '9'; c++ )
  47.     {
  48.       is_space[ c ] = 0;
  49.     }
  50.   for( c = 224; c < 256; c++ )
  51.     if( c != 247 )
  52.       {                         /* 247 is the division sign -:- */
  53.         d = c - 32;
  54.         is_space[ c ] = 0;
  55.         is_space[ d ] = 0;
  56.         if( c != 255 )          /* and don't convert '"y' to 'ss' : ) */
  57.           to_upper[ c ] = d;
  58.       }
  59.   if( case_sense )              /* destroy the to_upper[] table again */
  60.     for( c = 0; c < 256; c++ )
  61.       to_upper[ c ] = c;
  62.   is_space[ 0 ] = 0;            /* important, will be taken advantage of! */
  63. }
  64.  
  65.  
  66.  
  67. /* 
  68.  * str_cmp() will work like strcmp() if( case_sense && bordermode == 3 ),
  69.  * but can change its behaviour depending on those variables.
  70.  * Will also indicate by special (but legal) return values if <s> was an
  71.  * abbreviation of <t> or vice versa.
  72.  */
  73. int str_cmp( UBYTE *s, UBYTE *t )
  74. {
  75.   if( bordermode < 3 )
  76.     {                           /* modes where number of 'spaces' doesn't count */
  77.       while( is_space[ *s ] )
  78.         s++;                    /* advance to first word */
  79.       while( is_space[ *t ] )
  80.         t++;
  81.       while( to_upper[ *s ] == to_upper[ *t ] )
  82.         {
  83.           if( *s == '\0' )
  84.             return 0;
  85.           s++;
  86.           t++;
  87.           if( !bordermode || (is_space[ *s ] && is_space[ *t ]) )
  88.             {
  89.               /* both at the end of a word OR in sloppy bordermode */
  90.               while( is_space[ *s ] )
  91.                 s++;            /* skip the spaces */
  92.               while( is_space[ *t ] )
  93.                 t++;
  94.             }
  95.         }
  96.     }
  97.   else
  98.     {
  99.       while( to_upper[ *s ] == to_upper[ *t ] )
  100.         {
  101.           if( *s == '\0' )
  102.             return 0;
  103.           s++;
  104.           t++;
  105.         }
  106.     }
  107.   if( *s == '\0' )
  108.     return STR_SHORTER;
  109.   else if( *t == '\0' )
  110.     return STR_LONGER;
  111.   else
  112.     return( to_upper[ *s ] - to_upper[ *t ] );
  113. }
  114.  
  115.  
  116.  
  117. /* 
  118.  * The same as str_cmp(), but will only compare up to <n> characters.
  119.  * (Only two lines of code are different.)
  120.  */
  121. int strn_cmp( UBYTE *s, UBYTE *t, size_t n )
  122. {
  123.   if( bordermode < 3 )
  124.     {
  125.       while( is_space[ *s ] )
  126.         s++;
  127.       while( is_space[ *t ] )
  128.         t++;
  129.       while( to_upper[ *s ] == to_upper[ *t ] )
  130.         {
  131.           if( --n == 0 || *s == '\0' )
  132.             return 0;           /* that's the difference */
  133.           s++;
  134.           t++;
  135.           if( !bordermode || (is_space[ *s ] && is_space[ *t ]) )
  136.             {
  137.               while( is_space[ *s ] )
  138.                 s++;
  139.               while( is_space[ *t ] )
  140.                 t++;
  141.             }
  142.         }
  143.     }
  144.   else
  145.     {
  146.       while( to_upper[ *s ] == to_upper[ *t ] )
  147.         {
  148.           if( --n == 0 || *s == '\0' )
  149.             return 0;           /* and here once more */
  150.           s++;
  151.           t++;
  152.         }
  153.     }
  154.   if( *s == '\0' )
  155.     return STR_SHORTER;
  156.   else if( *t == '\0' )
  157.     return STR_LONGER;
  158.   else
  159.     return( to_upper[ *s ] - to_upper[ *t ] );
  160. }
  161.  
  162.  
  163.  
  164. /* 
  165.  * Find a copy of t in s, like strstr( )does.
  166.  * Note that bordermode has NO effect here!
  167.  */
  168. UBYTE *str_str( UBYTE *s, UBYTE *t )           
  169. {
  170.   int c;
  171.  
  172.   while( *s )
  173.     {
  174.       c = str_cmp( s, t );
  175.       if( c == 0 || c == STR_LONGER )
  176.         return s;
  177.       s++;
  178.     }
  179.   return NULL;
  180. }
  181.  
  182.  
  183.  
  184. /* 
  185.  * Some user info printed to <stdout>.
  186.  */
  187. void print_strstat( void )
  188. {
  189.   printf( "string processing:\n" );
  190.   printf( "  upper-/lowercase: " );
  191.   if( case_sense )
  192.     printf( "strict\n" );
  193.   else
  194.     printf( "'ABC'='abc'\n" );
  195.   printf( "  word delimiters:  " );
  196.   switch( bordermode )
  197.     {
  198.     case 0:
  199.       printf( "'a,b c'='abc'\n" );
  200.       break;
  201.     case 1:
  202.       printf( "'a, b, c'='a,b c'\n" );
  203.       break;
  204.     case 2:
  205.       printf( "'a  b  c'='a b c'\n" );
  206.       break;
  207.     case 3:
  208.       printf( "strict\n" );
  209.       break;
  210.     }
  211. }
  212.  
  213.